package com.fqdf.framework.android.util;

import android.graphics.Bitmap;
import android.net.Uri;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import okhttp3.internal.Util;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;

public class FileUtil {

    private FileUtil() {
        super();
    }

    public static void obbFile(File file) throws IOException {
        obbFile(file, false);
    }

    public static void obbFile(File file, boolean append) throws IOException {
        if (file.exists()) {
            if (!append) {
                file.delete();
                file.createNewFile();
            }
        } else {
            obbDir(file.getParentFile());
            file.createNewFile();
        }
    }

    public static void obbDir(File file) {
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 删除文件
     *
     * @param file
     */
    public static boolean deleteFile(File file) {
        if (file.exists()) {
            if (file.isFile()) {
                return file.delete();
            }
        }
        return false;
    }

    /**
     * 删除文件
     *
     * @param path
     */
    public static boolean deleteFile(String path) {
        if (!CheckLogicUtil.isEmpty(path)) {
            return deleteFile(new File(path));
        }
        return false;
    }

    /**
     * 保存一个输入流到文件
     *
     * @param is
     * @param saveFile
     * @throws IOException
     */
    public static void writeToFile(InputStream is, File saveFile) throws IOException {
        OutputStream os = new FileOutputStream(saveFile);
        int bytesRead = 0;
        byte[] buffer = new byte[1024];
        while ((bytesRead = is.read(buffer, 0, 1024)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        is.close();
    }

    /**
     * 保存一个输入流到文件
     *
     * @param is
     * @param saveFile
     * @throws IOException
     */
    public static void writeToFile(InputStream is, String saveFile) throws IOException {

    }

    /**
     * 保存一个str到文件
     *
     * @param file
     * @param str
     * @throws IOException
     */
    public static void writeStrToFile(File file, String str) throws IOException {
        obbFile(file, false);
        FileOutputStream outStream = new FileOutputStream(file);
        outStream.write(str.getBytes());
        outStream.flush();
        outStream.close();
    }

    /**
     * bitmap2file
     *
     * @param bitmap
     * @param f
     */
    public static void Bitmap2File(Bitmap bitmap, File f) {
        try {
            FileOutputStream out = new FileOutputStream(f);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从文件中获取str内容
     *
     * @param filePath
     * @return
     * @throws IOException
     */
    public static String readStrFromFile(String filePath) throws IOException {
        InputStream is = new FileInputStream(new File(filePath));
        String s = readStrFromInputStream(is);
        is.close();
        return s;
    }

    /**
     * 判断是否存在文件
     *
     * @param path 文件路径
     * @return
     */
    public static boolean isExists(String path) {
        boolean result = false;
        if (!CheckLogicUtil.isEmpty(path)) {
            result = new File(path).exists();
        }
        return result;
    }

    /**
     * 从输入流中读取字符串
     *
     * @param is
     * @return
     * @throws IOException
     */
    public static String readStrFromInputStream(InputStream is) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        StringBuffer buffer = new StringBuffer();
        String line = "";
        while ((line = in.readLine()) != null) {
            buffer.append(line);
        }
        in.close();
        return buffer.toString();
    }

    /**
     * 获取缓存文件名
     *
     * @param url 文件的url
     * @return
     */
    public static String converUrlToName(String url) {
        Uri parse = Uri.parse(url);
        String params = parse.getQuery();
        String result;
        if (CheckLogicUtil.isEmpty(params)) {
            result = parse.getLastPathSegment();
        } else {
            result = params.replace('=', '_').replace('&', '_') + parse.getLastPathSegment();
        }

        return result;
    }

    /**
     * 得到文件的名字，不包含路径
     *
     * @return 文件名
     */
    public static String getFileName(File file) {
        if (file != null && !file.isDirectory()) {
            String fileName = file.getName();

            return fileName.substring(0, fileName.length()
                    - getExtension(fileName).length());
        }
        return null;
    }

    /**
     * 得到文件的名字，不包含路径
     *
     * @param name 文件路径
     * @return 文件名
     */
    public static String getFileName(final String name) {
        String trueName = name;
        int index = name.lastIndexOf(Constants.SLASH);
        if (index > -1) {
            trueName = trueName.substring(index + 1);
        }
        int extensionSize = getExtension(trueName).length();
        if (extensionSize > 0) {
            trueName = trueName.substring(0, trueName.length() - extensionSize);
        }
        return trueName;
    }

    /**
     * 得到文件的名字，包含路径
     *
     * @param name 文件路径
     * @return 文件名
     */
    public static String getFileNameAndExtend(final String name) {
        String trueName = name;
        int index = name.lastIndexOf(Constants.SLASH);
        if (index > -1) {
            trueName = trueName.substring(index + 1);
        }
        return trueName;
    }

    /**
     * 得到文件的扩展名
     *
     * @param uri 文件名或者文件uri
     * @return 返回文件的扩展名，如果文件名是null则返回null 如果文件没有扩展名则返回空
     */
    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(Constants.POINT);
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            return Constants.BLANK;
        }
    }

    /**
     * byte2File
     *
     * @param buf
     */
    public static void byte2File(byte[] buf, File f) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(f);
            bos = new BufferedOutputStream(fos);
            bos.write(buf);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 拷贝文件
     * @param originFile 文件的原始位置
     * @param desFile 文件要拷贝的目标位置
     * @return true 代表拷贝成功 false 拷贝失败
     */
    public static boolean copyFileTo(File originFile, File desFile) {
        if (originFile == null || desFile == null) {
            return false;
        }
        if (!originFile.getParentFile().exists()) {
            originFile.getParentFile().mkdirs();
        }

        if (!desFile.getParentFile().exists()) {
            desFile.getParentFile().mkdirs();
        }

        BufferedSink bufferedSink = null;
        BufferedSource bufferedSource = null;
        try {
            bufferedSink = Okio.buffer(Okio.sink(desFile));
            bufferedSource = Okio.buffer(Okio.source(originFile));

            bufferedSink.writeAll(bufferedSource);
            bufferedSink.emit();
            bufferedSink.flush();
            return true;
        }  catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            Util.closeQuietly(bufferedSink);
            Util.closeQuietly(bufferedSource);
        }
    }

    /**
     * 剪切文件从原始位置到目标位置
     * @param originFile 文件的原始位置
     * @param desFile 文件的目标位置
     * @return true剪切成功 false 剪切失败
     */
    public static boolean cutFileTo(File originFile, File desFile){
        if(copyFileTo(originFile,desFile)){
            return deleteFile(originFile);
        }
        return false;
    }
}